/*
 * Copyright 2025 arisgo@163.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.arisgo.cloud.attendance.clazz.service.impl;

import com.arisgo.cloud.attendance.clazz.entity.ClassStaff;
import com.arisgo.cloud.attendance.clazz.entity.Staff;
import com.arisgo.cloud.attendance.clazz.mapper.ClassStaffMapper;
import com.arisgo.cloud.attendance.clazz.service.ClassStaffService;
import com.arisgo.cloud.attendance.clazz.vo.ClassInfoDetailVo;
import com.arisgo.cloud.attendance.clazz.vo.ClassStaffVo;
import com.arisgo.cloud.attendance.clazz.vo.StaffClassDetailVo;
import com.arisgo.cloud.attendance.clazz.vo.StaffVo;
import com.arisgo.cloud.common.Pagination;
import com.arisgo.cloud.common.dynamic.Header;
import com.arisgo.cloud.common.dynamic.Table;
import com.arisgo.cloud.common.utils.DateUtil;
import com.arisgo.cloud.common.utils.StringUtil;
import com.arisgo.cloud.web.mybatis.service.CloudServiceImpl;
import com.arisgo.cloud.web.param.Paging;
import com.arisgo.cloud.web.param.Param;
import com.arisgo.cloud.web.utils.RequestUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.time.LocalDate;
import java.util.List;
import java.util.Map;

/**
 * @author Coulson
 * @since 2024-12-31
 */
@Service
@AllArgsConstructor
public class ClassStaffServiceImpl extends CloudServiceImpl<ClassStaffMapper, ClassStaff, ClassStaffVo> implements ClassStaffService {

    @Override
    public ClassStaff getInstanceModel() {
        return new ClassStaff();
    }

    @Override
    public ClassStaffVo getInstanceVo() {
        return new ClassStaffVo();
    }

    @Override
    public Pagination<ClassStaffVo> findStaffByClassId(Long classId, Paging paging) {
        paging.addTenantIdParam(RequestUtil.getTenantId());
        paging.addParam(Param.creator(StringUtil.underlineToCamel(ClassStaff.CLASS_ID), classId));
        Map<String, Object> params = paging.convertMap();

        PageHelper.startPage(paging.getPageNo(), paging.getPageSize());
        PageInfo<ClassStaffVo> page = new PageInfo<>(this.mapper.findStaffByClassId(params));
        return Pagination.creator(page.getPageNum(), page.getPageSize(), page.getTotal(), page.getList());
    }

    @Override
    public Table<Pagination<?>> pageStaffClass(Long tenantId, LocalDate start, LocalDate end, Paging paging) {
        // 时间只要有一个为空，则取默认值
        if (start == null || end == null) {
            start = DateUtil.weekFirstDay(LocalDate.now());
            end = DateUtil.weekLastDay(LocalDate.now());
        }
        Table<Pagination<?>> table = new Table<>();
        // 设置表头
        List<Header> headers = Lists.newArrayList();
        headers.add(new Header("姓名", Staff.NAME, true));
        headers.add(new Header("工号", Staff.CODE, true));
        LocalDate head = start;
        while (!head.isAfter(end)) {
            Header header = new Header();
            header.setLabel(DateUtil.formatWeek(head) + "(" + head.getMonthValue() + "." + head.getDayOfMonth() + ")");
            header.setField(DateUtil.format(head));
            headers.add(header);
            head = head.plusDays(1);
        }
        table.setHeaders(headers);

        // 分页查询已排班人员数据
        paging.addTenantIdParam(tenantId);
        Map<String, Object> params = paging.convertMap();
        Long total = this.mapper.pageStaffClassCount(params);
        List<StaffVo> staffs = this.mapper.pageStaffClass(params);

        if (CollectionUtils.isEmpty(staffs)) {
            table.setData(Pagination.creator(paging.getPageNo(), paging.getPageSize(), total, Lists.newArrayList()));
            return table;
        }
        // 查询班次信息
        List<Long> staffIds = staffs.stream().map(StaffVo::getId).toList();
        List<StaffClassDetailVo> classInfos = this.mapper.findStaffClassDetail(tenantId, start, end, staffIds);

        Map<String, Map<String, Object>> classMap = Maps.newHashMapWithExpectedSize(staffs.size());
        for (StaffClassDetailVo classInfo : classInfos) {
            String staffCode = classInfo.getStaffCode();
            Map<String, Object> map = classMap.get(staffCode);
            if (CollectionUtils.isEmpty(map)) {
                map = Maps.newHashMapWithExpectedSize(headers.size());
                map.put(Staff.ID, classInfo.getStaffId());
                map.put(Staff.CODE, staffCode);
                map.put(Staff.NAME, classInfo.getStaffName());
                classMap.put(staffCode, map);
            }
            map.put(DateUtil.format(classInfo.getWorkDate()), classInfo.getShiftName());
        }
        table.setData(Pagination.creator(paging.getPageNo(), paging.getPageSize(), total, classMap.values().stream().toList()));
        return table;
    }

    @Override
    public Table<Pagination<?>> pageStaffWeek(Long tenantId, LocalDate date, Paging paging) {
        if (null == date) {
            date = LocalDate.now();
        }
        LocalDate start = DateUtil.weekFirstDay(date);
        LocalDate end = DateUtil.weekLastDay(date);
        return pageStaffClass(tenantId, start, end, paging);
    }

    @Override
    public List<ClassInfoDetailVo> findClassDetailByStaff(Long staffId, LocalDate date) {
        Long tenantId = RequestUtil.getTenantId();
        return this.mapper.findClassByStaff(tenantId, staffId, date);
    }
}
